class Compiler {
  constructor(el, vm) {
    this.vm = vm;
    this.bracContent = /\{\{[\s](.*)[\s]\}\}/
    this.el = document.querySelector(el)
    if(this.el) {
      this.compile(this.el)
      vm.$mounted()
    }
  }

  compile(el) {
    const ndoes = el.childNodes;
    Array.from(ndoes).forEach(node => {
      if(this.isElement(node)) {
        const attrs = node.attributes;
        Object.keys(attrs).forEach(key=> {
          const name = attrs[key].name
          const value = attrs[key].value
          if(name.startsWith('v-')) {
            const key = name.substring(2)
            if(this[key]) {
              if(/^v-for$/g.test('v-for')) {
                this[key](node, value)
              } else {
                this[key](node, value)
              }
            }
          }
          if(name.startsWith('v-on:')) {
            new Incident(this.vm, node, name.substring(5), value);
          }
          if(name.startsWith('@')) {
            // node.onclick = ()=> {
            //   return this.vm.$methods[value].call(this.vm)
            // }
            new Incident(this.vm, node, name.substring(1), value);
          }
        })
      }
      if (this.isText(node)) {
        const txt = node.textContent;
        const name = RegExp.$1;
        if(this.vm[name]) {
          // node.textContent = txt.replace(this.bracContent, this.vm[name])
          // 监听
          this.template(node, name)
          // document.addEventListener(name, e=>{
          //   // 监听当前 name名称 替换DOM内容
          //   node.textContent = txt.replace(this.bracContent, this.vm[name])
          // })
        }
      }
      if(node.childNodes && node.childNodes.length >= 0) {
        this.compile(node)
      }
    })
  }

  isElement(node) {
    return node.nodeType === 1
  }

  isText(node) {
    return node.nodeType === 3 && this.bracContent.test(node.textContent)
  }


  if(node, value) {
    if(node.parentNode && value) {
      node.parentNode.removeChild(node)
    }
  }
  show(node, value) {
    node.style.display = value ? 'block' : 'none'
  }

  for(node, val) {
    const format = val.split(' ');
    const list = this.vm[format[2]]
    const ele = node.localName;
    let html = '';
    // /\{\{\s*([^\s\{\}]+)\s*\}\}/g.test(html)
    // console.log(RegExp.$1, RegExp.$2, RegExp.$3)
    for(const item of list) {
      // const e = document.createElement(ele);
      // e.innerHTML = item
      // node.appendChild(e)
      html += `<${ele}>${item}</${ele}>`
    //   node.appendChild(html)
    }
    node.innerHTML = html
  }

  model(node, value) {
    node.value = this.vm[value]
    node.addEventListener('input', (e)=> {
      this.vm[value] = e.target.value
    })
    
  }
  
  // modelupdate(node, value) {
    
  // }

  update(node, key, value) {
    const fn = this[ key + 'update' ]
    if(fn) {
      fn.call(this.vm, node, this.vm[value])
      new Watcher(this.vm, value, function(value) {
        fn.call(this.vm,node, value)
      })
    }
  }
  htmlupdate(node, value) {
    node.innerHTML = value
  }
  html(node, value) {
    this.update(node, 'html', value)
  }
  textupdate(node, value) {
    node.textContent = value
  }
  text(node, value) {
    this.update(node, 'text', value)
  }
  template(node, value) {
    this.update(node, 'template', value)
  }
  templateupdate(node, value) {
    // node.textContent = node.textContent.replace(/\{\{[\s](.*)[\s]\}\}/, value)
    node.textContent = value
  }
}

